
# -*- coding: utf-8 -*-
# @Author: Tim Liu 
# @Date: 2024-10-14
# @Last Modified by: Tim Liu
# @Last Modified time: 2025-01-22

# @Description: Conversation Service, manages the conversation between the user and the bot.

import uuid
import json
from datetime import datetime
from abc import ABC, abstractmethod

from crewplus.apps.conversation.schemas import Conversation

class ConversationService(ABC):
    """
    Base Conversation Service, manages the conversation between the user and the bot (session separation). 
    It provides methods to create a new conversation, get the conversation history messages.
    """

    def __init__(self, model: str = None):
        self.model = model

    @abstractmethod
    def add_message(self, conversation_id: str, message: str = None, type: str = "user"):
        pass

    @abstractmethod
    def get_history_messages(self, conversation_id: str):
        pass

    def new_conversation(self, user_id: int = 0):
        # Create a new conversation in the database, save the conversation_id, user_id and start time
        data = Conversation()
        data.session_id = uuid.uuid4()
        data.create_user_id = user_id
        data.converse_start_time = str(datetime.now())

        return data

    def extract_answer(self, chunk: str):
        chunk = chunk.strip()
        if chunk.startswith("{") and chunk.endswith("}"):
            # If the chunk is enclosed in curly braces, try to extract the value
            try:
                key_value_pair = chunk[1:-1].split(":")
                key = key_value_pair[0].strip()
                value = key_value_pair[1].strip()

                print(key)
                if key.startswith("'") and key.endswith("'"):
                    key = key[1:-1]  

                # Remove outermost single quotes if present
                if value.startswith("'") and value.endswith("'"):
                    value = value[1:-1]  

                if key == 'answer':
                    return value
                else:
                    return None
            except (ValueError, IndexError):
                # Handle potential parsing errors
                return None
        else:
            # If the chunk is not enclosed in curly braces, return None
            return None

    def add_message_chunk(self, message: str, chunk) -> str:
        # add text chunk to message
        # case 1: "{ 'answer': ' hello' }"; case 2: "this is a chunk"; case 3: "{{'key': 'value'}}"
        strValue = self.extract_answer(chunk)
        
        if strValue:
            message += strValue
        
        return message

    def json_to_string(self, json_string: str):
        """Converts a serialized JSON string to a string.

        Args:
            json_string: The serialized JSON string representing the Message.

        Returns:
            A message string.
        """
        message_dict = json.loads(json_string)

        return message_dict['type'] + ': ' + message_dict['data']['content']